#include <iostream>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdint.h>
#include <string>
#include <memory>
#include <cstring>
#include <netinet/in.h>
#include <arpa/inet.h>

class TcpClient
{
public:
    TcpClient(std::string ip,int port)
        :_sockfd(-1)
        ,_server_ip(ip)
        ,_server_port(port)
    {}

    void Request()
    {
        std::string msg;
        char buffer[1024];
        while(true)
        {
            std::cout << "Please Enter#";
            getline(std::cin,msg);
            write(_sockfd,msg.c_str(),msg.size());

            ssize_t size = read(_sockfd,buffer,sizeof(buffer) - 1);
            if(size > 0)
            {
                //读取成功
                buffer[size] = '\0';
                std::cout << "server echo#" << buffer << std::endl;
            }
            else if(size == 0)
            {
                //对端关闭
                std::cout << "server close!" << std::endl;
                break;
            }
            else
            {
                //读取出错
                std::cout << "read error" << std::endl;
                break;
            }
        }
    }

    void Start()
    {
        struct sockaddr_in peer;
        bzero(&peer,sizeof(peer));

        peer.sin_family = AF_INET;
        peer.sin_port = htons(_server_port);
        peer.sin_addr.s_addr = inet_addr(_server_ip.c_str());

        if(connect(_sockfd,(struct sockaddr*)&peer,sizeof(peer)) == 0)
        {
            //连接成功
            std::cout << "connect success..." << std::endl;
            //发起请求
            Request();
        }
        else
        {
            //连接失败
            std::cout << "connenct failed..." << std::endl;
            exit(3);
        }
    }

    void InitClient()
    {
        //创建套接字
        _sockfd = socket(AF_INET,SOCK_STREAM,0);
        if(_sockfd < 0)
        {
            std::cout << "socket error" << std::endl;
            exit(2);
        }
    }
    ~TcpClient()
    {
        if(_sockfd >= 0)
        {
            close(_sockfd);
        }
    }
private:
    int _sockfd;
    std::string _server_ip;
    int _server_port;
};